package com.sky.service.admin.impl;

import cn.hutool.core.date.DateException;
import com.sky.constant.MessageConstant;
import com.sky.mapper.user.OrdersMapper;
import com.sky.mapper.user.UserMapper;
import com.sky.pojo.Orders;
import com.sky.service.admin.ReportService;
import com.sky.vo.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Transactional(readOnly = true)
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired WorkspaceServiceImpl workspaceService;

    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        if (null == begin || null == end || begin.isAfter(end)) {
            throw new DateException(MessageConstant.DATA_ERROR);
        }
        List<String> dateList = new ArrayList<>();
        while (!begin.isAfter(end)) {
            dateList.add(begin.toString());
            begin = begin.plusDays(1);
        }
        List<Double> turnoverList = new ArrayList<>();

       /* for (String date : dateList) {
            Double amount = ordersMapper.selectAmountByDate(date);
            if (null == amount) {
                amount = 0.0;
            }
            turnoverList.add(amount);
        }*/
        Map<String, Object> map = ordersMapper.selectAmountByDate2(dateList);
        for (String date : dateList) {
            Object amount = map.get(date);
            turnoverList.add(Double.parseDouble(amount.toString()));
        }

        TurnoverReportVO vo = TurnoverReportVO.builder()
                .turnoverList(StringUtils.join(turnoverList, ","))
                .dateList(StringUtils.join(dateList, ","))
                .build();
        return vo;
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        if (null == begin || null == end || begin.isAfter(end)) {
            throw new DateException(MessageConstant.DATA_ERROR);
        }
        LocalDate beginTime = begin;
        List<String> dateList = new ArrayList<>();
        while (!begin.isAfter(end)) {
            dateList.add(begin.toString());
            begin = begin.plusDays(1);
        }
        List<Integer> totalUserList = new ArrayList<>(dateList.size());
        int beginCount = userMapper.selectCountBybegin(beginTime);
        Map<String, Object> map = userMapper.selectSaveByDate(dateList);
        List<Integer> newUserList = new ArrayList<>(dateList.size());
        for (String date : dateList) {
            Object newCount = map.get(date);
            newUserList.add(Integer.parseInt(newCount.toString()));
            beginCount += Integer.parseInt(newCount.toString());
            totalUserList.add(beginCount);
        }
        UserReportVO vo = UserReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .newUserList(StringUtils.join(newUserList, ","))
                .totalUserList(StringUtils.join(totalUserList, ","))
                .build();
        return vo;
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        if (null == begin || null == end || begin.isAfter(end)) {
            throw new DateException(MessageConstant.DATA_ERROR);
        }
        LocalDate beginTime = begin;
        List<String> dateList = new ArrayList<>();
        while (!begin.isAfter(end)) {
            dateList.add(begin.toString());
            begin = begin.plusDays(1);
        }
        int orderCount1 = ordersMapper.selectCountOrStatus(beginTime, end, Orders.COMPLETE_ORDER);
        int orderCount2 = ordersMapper.selectCountOrStatus(beginTime, end, null);

        Map<String,Object> map1=  ordersMapper.selectOrderCountByDate(dateList,Orders.COMPLETE_ORDER);
        Map<String, Object> map2 = ordersMapper.selectOrderCountByDate(dateList, null);

        List<String>validOrderCountList=new ArrayList<>(dateList.size());
        List<String>orderCountList=new ArrayList<>(dateList.size());
        for (String date : dateList) {
            Object validOrderCountDay = map1.get(date);
            Object OrderCount = map2.get(date);
            validOrderCountList.add(validOrderCountDay.toString());
            orderCountList.add(OrderCount.toString());
        }
        Double orderCompletionRate=orderCount1 * 1.0 / orderCount2;
        if (orderCount2==0){
            orderCompletionRate=0.0;
        }
        OrderReportVO vo = OrderReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .orderCountList(StringUtils.join(orderCountList, ","))
                .validOrderCountList(StringUtils.join(validOrderCountList, ","))
                .totalOrderCount(orderCount2)
                .orderCompletionRate(orderCompletionRate)
                .validOrderCount(orderCount1)
                .build();
        log.info("响应参数---{}",vo);
        return vo;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        if (null==begin||null==end||begin.isAfter(end)){
            throw new DateException(MessageConstant.DATA_ERROR);
        }
        LocalDate beginTime=begin;
        List<String>dateList=new ArrayList<>();
        while (!begin.isAfter(end)){
            dateList.add(begin.toString());
            begin= begin.plusDays(1);
        }
        List<Map>list=ordersMapper.selectDishByDate(beginTime,end);
        List<String>numberList=new ArrayList<>(dateList.size());
        List<String>nameList=new ArrayList<>(dateList.size());
        for (Map map : list) {
            Object name = map.get("name");
            nameList.add(name.toString());
            Object num = map.get("num");
            numberList.add(num.toString());
        }
        SalesTop10ReportVO vo = SalesTop10ReportVO.builder()
                .numberList(StringUtils.join(numberList, ","))
                .nameList(StringUtils.join(nameList, ","))
                .build();
        return vo;

    }

    @Override
    public void export(HttpServletResponse response) throws IOException {
        LocalDate begin=LocalDate.now().minusDays(30);
        LocalDate end=LocalDate.now().minusDays(1);
        //类加载器
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("static/运营数据报表模板.xlsx");
        //调用之前写好的service
        BusinessDataVO businessDate = workspaceService.businessDate(begin,end);
        //创建Excel 用流读取
        XSSFWorkbook excel = new XSSFWorkbook(is);
        XSSFSheet sheet = excel.getSheetAt(0);
        //设置第二行第二列
        sheet.getRow(1).getCell(1).setCellValue(begin+"至"+end);
        //设置第4行数据
        XSSFRow row3 = sheet.getRow(3);
        row3.getCell(2).setCellValue(businessDate.getTurnover());
        row3.getCell(4).setCellValue(businessDate.getOrderCompletionRate());
        row3.getCell(6).setCellValue(businessDate.getNewUsers());
        //设置第5行数据
        XSSFRow row5 = sheet.getRow(4);
        row5.getCell(2).setCellValue(businessDate.getValidOrderCount());
        row5.getCell(4).setCellValue(businessDate.getUnitPrice());
        //设置明细数据
        for (int i = 0; i < 30; i++) {
            //调用之前写好的service
            BusinessDataVO vo = workspaceService.businessDate(begin,begin);
            XSSFRow row = sheet.getRow(7 + i);
            row.getCell(1).setCellValue(begin.toString());
            row.getCell(2).setCellValue(vo.getTurnover());
            row.getCell(3).setCellValue(vo.getValidOrderCount());
            row.getCell(4).setCellValue(vo.getOrderCompletionRate());
            row.getCell(5).setCellValue(vo.getUnitPrice());
            row.getCell(6).setCellValue(vo.getNewUsers());
            begin= begin.plusDays(1);
        }
        //通过输出流将文件下载到客户端浏览器重
        ServletOutputStream outputStream = response.getOutputStream();
        excel.write(outputStream);
        //关闭资源
        excel.close();
        outputStream.close();
    }
}